//开锁使用的图案线路(可使用开发者模式-->指针位置 确认坐标,按键锁同理)
var pointArray = [[250, 1415], [540, 1415], [830, 1415], [540, 1705], [250, 1995], [540, 1995], [830, 1995]];
//主方法
main();

function main() {
    //最高重复收割60次好友能量
    let max = 60;
    while (max--) {//直接改为true,一直收割一直爽
        harvestAntForestEnergy();
		//隔一分钟再次收割蚂蚁森林能量
        sleep(60*1000)
    }
}

/**
 * 收割蚂蚁森林能量
 */
function harvestAntForestEnergy() {
    //启动无障碍服务
    accessibilityServices();
    //点亮屏幕
    screenLight(10);
	//判断是否在可以收割能量的页面(自己的主页/朋友的主页)
    if (!inMyAntForestHome() && !inFriendAntForestHome()) {
        //不在这两个页面 先进入蚂蚁森林
        intoMaYi(20, 2000);
    }
	//二话不说先收割一波能量
	collectEnergy(10);
	//循环收割朋友能量
	stealEnergy();
    //返回我的蚂蚁森林
    backHome();
}

/* 检测“无障碍服务”是否开启 */
function accessibilityServices() {
    try {
        auto(); // 如果无障碍服务未启动会停止脚本
        // auto.setMode("fast"); // 启用控件缓存，从而选择器获取屏幕控件更快
        // auto.waitFor(); // 在无障碍服务启动后继续运行
    } catch (error) {
        getError("无障碍服务启动失败");
    }

    return getLog("无障碍服务启动成功");
}

/**
 * 点亮屏幕
 * @param max_try_times 最大尝试次数
 */
function screenLight(max_try_times) {
    let maxTimes = max_try_times;
    if (!device.isScreenOn()) {
        while (!device.isScreenOn() && max_try_times--) {
            getLog("尝试点亮屏幕: " + (maxTimes - max_try_times) + "次");
            device.wakeUp();
            sleep(500);
        }
        if (max_try_times < 0) {
            getError("点亮屏幕失败");
        }
    }
	//点亮后判断当前界面在哪个位置
	//判断当前位置是否在锁屏界面
	if (isLockPlan()) {
		//如果不在键盘锁面板,需要先获取到键盘锁界面
		if (!isKeyboardLockPlan()) {
			//获取键盘锁面板
			getLockPanel(20, 240, 80, 1200);
		}
		//绘制解锁线条
		drawLine(20, 1500, 10, pointArray);
	}
}

/**
 * 获取键盘锁面板
 * @param max_try_times 最大尝试次数
 * @param swipe_time 初始滑动过程时间
 * @param swipe_time_increment 滑动过程时间增量
 * @param HEIGHT 滑动点高度
 */
function getLockPanel(max_try_times, swipe_time, swipe_time_increment, HEIGHT) {
    let maxTimes = max_try_times;
    while (!isKeyboardLockPlan() && max_try_times--) {
        getLog("尝试获取锁面板: " + (maxTimes - max_try_times) + "次");
        swipe_time += swipe_time_increment;
        //模拟手势
        gesture(swipe_time, [540, HEIGHT * 0.9], [540, HEIGHT * 0.1]);
        sleep(1000);
    }
    if (max_try_times < 0) {
        getError("上滑屏幕失败");
    } else {
        getLog("成功获取锁面板");
    }
}

/**
 * 绘制手势
 * @param max_try_times 最大尝试唤出锁屏密码界面此时
 * @param swipe_time 初始滑动时间 找出最佳时间可以直接使用那个时间进行绘制手势
 * @param swipe_time_increment 滑动过程时间增量
 */
function drawLine(max_try_times, swipe_time, swipe_time_increment, pointArray) {
	//没有传入绘制手势路径使用默认的开机路径
	if(!pointArray){
		pointArray = [[250, 1415], [540, 1415], [830, 1415], [540, 1705], [250, 1995], [540, 1995], [830, 1995]];
	}
    let maxTimes = max_try_times;
    while (isKeyboardLockPlan() && max_try_times--) {
        getLog("尝试绘制密码: " + (maxTimes - max_try_times) + "次");
        swipe_time += swipe_time_increment;
        //模拟手势
        gesture(swipe_time, pointArray);
        sleep(1000);
    }
    if (max_try_times < 0) {
        getError("解锁失败");
    } else {
        getLog("解锁成功");
    }
}

/**
 * 进入蚂蚁森林
 * @param max_try_times 最大尝试次数
 * @param time_interval 重试时间间隔
 */
function intoMaYi(max_try_times, time_interval) {
    getLog("进入'蚂蚁森林' start...");
    let enter_flag = 1; // 0: success 1:fail
    for (let index = 0; index <= max_try_times; index++) {

        /* 通过下面三个"控件"来判断成功进入了蚂蚁森林 */
        let close_exist = className("android.widget.TextView").desc("关闭").exists();
        let stock_tree_exist = className("android.widget.Button").text("种树").exists();
        let look_tree_exist = className("android.widget.Button").text("看林区").exists();
        if (close_exist
            && stock_tree_exist
            && look_tree_exist) {
            enter_flag = 0;
            break;
        } else {
            if (index) {
                debug_str = "尝试进入蚂蚁森林: " + index + " 次.\n    close: " + close_exist
                    + ", stock_tree: " + stock_tree_exist + " mytree: " + look_tree_exist;
                getLog(debug_str);
            }
        }
        /* 如何获取data(支付宝客户端的标准scheme)(简而言之：百度)
        * http://myjsapi.alipay.com/jsapi/h5app-lifecycle.html
        * https://www.jianshu.com/p/5ea0b9d84caa
        * (百度)获取得到蚂蚁森林的scheme("URL"): alipay://platformapi/startapp?appId=60000002
        * packageName:通过Auto.js的"布局分析"可以获得
        */
        app.startActivity({
            action: "android.intent.action.VIEW",
            data: "alipays://platformapi/startapp?appId=60000002",
            packageName: "com.eg.android.AlipayGphone"
        });
        sleep(time_interval);
    }
    let buttons = className("android.view.View").text("startapp?appId=60000002&url=%2Fwww%2Fhome").find();
    buttons.forEach (function (object){
        click(object.bounds().centerX(), object.bounds().centerY());
        getLog("通过森林直接回主页")
    })

    /* 如果进入蚂蚁森林失败，则退出程序 */
    if (enter_flag) {
        getError("进入蚂蚁森林失败！");
    }
    getLog("进入'蚂蚁森林'成功 end...")
}

/**
 * 循环收割朋友能量
 * 不直接使用递归,因为使用递归会控件识别失败的问题原因未知
 */
function stealEnergy() {
    let count = 1;
    let status = 1;
    while (status == 1){
        getLog("进入朋友页面 第"+count+"个人");
        count++;
		//每次偷取完判断是否有下一个
        status = goToFriend(955,1555);
    }
    getLog("所有能量收割完成");
}

/**
 * 到朋友森林页面
 * @param x 逛一逛的坐标x
 * @param y 逛一逛的坐标y
 */
function goToFriend(x,y) {
	//点击逛一逛,可使用开发者模式-->指针位置 确认坐标
    click(x,y);
	//点击后休息两秒让控件完全加载出来再获取
    sleep(2000);
	
	//首先判断是否已经没有能量可收了
    let empty = className("android.view.View").text("startapp?appId=60000002&url=%2Fwww%2Fhome").exists();
    if (!empty){
		return 0;
    }
	
    //最大尝试五次
    let max_try_times = 5;
	//通过浇水和弹幕两个控件确认已经到了朋友森林主页,只需要其中一个回去到就可
    let isWatering = className("android.widget.Button").text("浇水").exists();
    let bullet_comment = className("android.widget.Button").text("弹幕").exists();
	getLog("isWatering: "+isWatering+"\n bullet_comment： "+bullet_comment+"\n max_try_times:"+max_try_times);
	while (max_try_times-- && !isWatering && !bullet_comment){
		//未获取到控件,间隔两秒重新获取,尝试5次
		sleep(2000);
		isWatering = className("android.widget.Button").text("浇水").exists();
		bullet_comment = className("android.widget.Button").text("弹幕").exists();
		getLog("isWatering: "+isWatering+"\n bullet_comment： "+bullet_comment+"\n max_try_times:"+max_try_times);
	}
	//只要有一个成功获取就代表在朋友森林主页,可以进行收割了
	getLog("最终判断是否在朋友主页 \n isWatering: "+isWatering+"\n bullet_comment： "+bullet_comment);
	if (isWatering || bullet_comment){
		collectEnergy(20);
		return 1;
	}
	return 0;
}

/**
 * 收割能量,只收割不帮忙收取效率会高点
 * 1. 确保已经进入自己的主页或者好友的主页
 * 2. 确定好能量球个数上限，可以防止其他异常情况导致死循环（有好友有保护罩导致死循环的情况。）
 * @param max_energy_num 最大能量个数
 * @returns {number}
 */
/*function onlyCollectEnergy (max_energy_num) {
    getLog("开始收割能量")
    let index = 0;
    if (className("android.widget.Button").exists()){
        let energy_button = className("android.widget.Button").textStartsWith("收集能量").find();
        energy_button.forEach (function (object){
            debug_str = "energy exist1: " + index + ", " + object.text();
            getLog(debug_str);
            // energy_button.click();
            click(object.bounds().centerX(), object.bounds().centerY());
            index++;
            if (index > max_energy_num) {
                getLog("收割能量结束，收割"+index+"次");
                return;
            }
            sleep(500);
        });
    }
    getLog("收割能量结束，收割"+index+"次");
}*/

/**
 * 帮忙收取+偷取能量
 * 1. 确保已经进入自己的主页或者好友的主页
 * 2. 确定好能量球个数上限，可以防止其他异常情况导致死循环（有好友有保护罩导致死循环的情况。）
 * @param max_energy_num 最大能量个数
 */
function collectEnergy (max_energy_num) {
    getLog("开始收割能量")
    //总点击次数
    let index = 0;
    //帮忙收取次数
    let index1 = 0;
    //偷取次数
    let index2 = 0;
	//获取所有的android.widget.Button控件
	//其中帮忙收取的能量球 text值为空
	//可以收割的能量球 text为"收集能量**克"
    let buttons = className("android.widget.Button").find();
    if(buttons.length>0){
        buttons.forEach (function (object){
            debug_str = "energy exist1: " + index + ", " + object.text();
            getLog(debug_str);
            let str=object.text();
            if(str == 'undefined' || !str || !/[^\s]/.test(str)){
                getLog("帮忙收取能量"+index1);
                clickEnergyBall(object);
                index++;
                index1++;
				if (index > max_energy_num) {
					getLog("帮忙收割能量提前结束，收割"+index1+"次");
					getLog("偷取能量提前结束，收割"+index2+"次");
					return;
				}
            }
            if (str.substring(0,4)=="收集能量"){
                getLog("偷取能量:"+index2);
                clickEnergyBall(object);
                index++;
                index2++;
				if (index > max_energy_num) {
					getLog("帮忙收割能量提前结束，收割"+index1+"次");
					getLog("偷取能量提前结束，收割"+index2+"次");
					return;
				}
            }

        })
    }
    getLog("帮忙收割能量结束，收割"+index1+"次");
    getLog("偷取能量结束，收割"+index2+"次");
}


/**
 * 点击能量球
 * @param object 需要点击的控件
 */
function clickEnergyBall(object) {
    click(object.bounds().centerX(), object.bounds().centerY());
    sleep(500);
}

/**
 * 返回主页
 */
function backHome(){
    getLog("返回我的主页开始")
	//使用蚂蚁森林内按钮返回自己的主页
    //let buttons = className("android.view.View").text("startapp?appId=60000002&url=%2Fwww%2Fhome").find();
    //buttons.forEach (function (object){
    //    click(object.bounds().centerX(), object.bounds().centerY());
    //})

    for (let i = 0;i > 5;i++) {
        if(!inMyAntForestHome()){
			clickBack();
			sleep(2000);
		}
    }
	getLog("返回我的主页结束");
}
//点击左上角的返回键回调主页
function clickBack() {
    getLog("开始点击返回")
    let close_menu_parent = id("h5_nav_back").findOne();
	getLog("返回按钮父层:"+close_menu_parent);
	let close_menu = close_menu_parent.child(0);
	getLog("返回按钮:"+close_menu);
    if (close_menu){
        click(close_menu.bounds().centerX(), close_menu.bounds().centerY());
        getLog("点击返回~~~")
    }
}

/**************公用方法****************/
//判断是否在键盘锁界面
function isKeyboardLockPlan() {
	//根据手机上键盘锁上显示的文字设置
    let lock = text("请用密码或指纹解锁").exists();
    getLog("查看是否在键盘锁界面"+lock);
    return lock;
}
//是否在锁屏界面(上滑解锁界面 + 键盘锁界面)
function isLockPlan() {
    let keyguard_manager = context.getSystemService(context.KEYGUARD_SERVICE);
    var flag = keyguard_manager.isKeyguardLocked();
    getLog("查看是否在锁屏界面:"+flag)
    return flag;
}
//是否在自己的蚂蚁森林主页
function inMyAntForestHome() {
    /* 通过下面三个"控件"来判断成功进入了蚂蚁森林 */
    let close_exist = className("android.widget.TextView").desc("关闭").exists();
    let stock_tree_exist = className("android.widget.Button").text("种树").exists();
    let look_tree_exist = className("android.widget.Button").text("看林区").exists();
    if (close_exist
        && stock_tree_exist
        && look_tree_exist) {
        return true;
    } else {
        debug_str = "close: " + close_exist
            + ", stock_tree: " + stock_tree_exist
            + ", mytree: " + look_tree_exist;
        getLog(debug_str);
		return false;
    }
	
}
//是否在朋友蚂蚁森林主页
function inFriendAntForestHome() {
    let isWatering = className("android.widget.Button").text("浇水").exists();
    let bullet_comment = className("android.widget.Button").text("弹幕").exists();
    if (isWatering
        && bullet_comment) {
        return true;
    } else {
        debug_str = "isWatering: " + isWatering
            + ", bullet_comment: " + bullet_comment;
        getLog(debug_str);
		return false;
    }
}
//打印日志
function getLog(msg) {
    console.log(msg);
}
//打印错误日志并退出脚本
function getError(msg) {
    console.log(msg);
    //退出脚本
    exit();
}
